﻿using Share;
using System.Collections.Generic;
using UnityEngine;
public class StateMachine : MonoBehaviour
{


    // Use this for initialization

    public List<StateBase> m_StateList = new List<StateBase>();
    //StateBehaviour m_stateBehaviore; // 动画的状态机
    [SerializeField]
    StateBase m_curState;
    StateBase m_lastState = null;

    [SerializeField]
    string m_strCurState = "";
    public StateBase GetCurState()
    {
        return m_curState;
    }
    public StateBase GetLastState()
    {
        return m_lastState;
    }
    public void DoAddState(string strKey, StateBase state)
    {
        state.DoInit(strKey, Owner);
        m_StateList.Add(state);
    }


    ObjectBase m_Owner;
    ObjectBase Owner
    {
        get
        {
            if (m_Owner == null)
            {
                m_Owner = GetComponent<ObjectState>();
                if (m_Owner == null)
                {
                    XKLog.LogError("行为机没有发现ObjectState载体，致命错误!!!!");
                }
            }
            return m_Owner;

        }
    }


    private void Start()
    {
    }
    //public void DoStateAnimEnd( int nNameHash )
    //{
    //    GetCurState().m_LuaState.OnAnimationEnd( nNameHash );
    //}

    StateBase GetStateByName(string strAction)
    {
        foreach (var item in m_StateList)
        {
            if (item.Name == strAction)
            {
                return item;
            }
        }
        return null;
    }
    public void DoSendEvent(EventParam param)
    {
        if (m_curState != null)
            m_curState.DoSendEvent(param);
    }

    public bool DoForceState(string strAction, EventParam param = null)
    {
        var newState = GetStateByName(strAction);
        if (m_curState != null)
            m_curState.DoForceEnd();
        m_strCurState = strAction;
        m_lastState = m_curState;
        m_curState = newState;
        m_curState.DoStart(param);

        Owner.DoSendStateEnterMessage(strAction);
        return true;
    }
    public bool DoSetState(string strAction, EventParam param = null, bool forceChange = false, bool bFromServer = false)
    {
        // 如果当前状态没变,就走这个状态下的重新开始
        // 如果当前状态存在
        if (m_curState != null && !forceChange)
        {
            // 判断当前状态和新状态是否一样，如果一样，就走restart的逻辑
            if (strAction == m_curState.Name)
            {
                return m_curState.DoRestart(param);
            }
            // 判断当前状态是不是可以被新的状态转变，因为有的状态会被锁住，不如攻击的时候不能移动。
            // 这个逻辑在lua里的对应的state里的 IsCanTransition 来做，
            if (!m_curState.IsCanTransition(strAction))
            {
                return false;
            }
        }
        // 得到新的状态逻辑
        var newState = GetStateByName(strAction);
        if (newState == null)
            return false;
        // 走到这里，说明状态可以切换了，先终止掉当前状态
        if (m_curState != null)
            m_curState.DoBreak();
        m_lastState = m_curState;
        m_curState = newState;
        // 切换到新的状态
        m_curState.DoStart(param);
        m_strCurState = strAction;
        if (bFromServer == false) // 如果是网络模块，还得告诉服务器一份
        {
            // 需要吧 param 参数发给服务器，进行转发
        }
        return true;

    }
    public void DoUpdate()
    {
        // 这里只会更新当前状态的逻辑
        if (m_curState != null)
        {
            m_curState.DoUpdate();
            //XKLog.Log(m_curState.m_strActionName);
        }
    }

    public void DoRelease()
    {
        if (m_StateList == null)
            return;
        foreach (var item in m_StateList)
        {
            item.DoRelease();
        }
    }
}
